package com.pragmatic.cryptography;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;

/**
 * AES工具类(对称加密算法)
 *
 * @author wangdong
 * @since 2025/4/22 9:52
 */
public class AESUtil {

  // 算法名称AES
  private static final String KEY_ALGORITHM = "AES";
  // 生成AES秘钥算法
  private static final String SHA_ALGORITHM = "SHA1PRNG";
  // AES/模式/填充方式
  private static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";

  /**
   * 每次生成一个随机字符串(用于生产AES秘钥)
   *
   * @return 随机字符串
   */
  public static String randomSecretKey() {
    return UUID.randomUUID().toString().replace("-", "");
  }

  /**
   * AES 加密操作
   *
   * @param content 待加密明文内容
   * @param key 秘钥
   * @return 返回Base64转码后的加密数据
   */
  public static String encrypt(String content, String key) {
    try {
      Cipher cipher = Cipher.getInstance(TRANSFORMATION);
      byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);
      // 通过随机串生成一个AES对称秘钥，然后使用该秘钥对content进行AES对称加密
      cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
      byte[] result = cipher.doFinal(byteContent);
      return new String(Base64.getEncoder().encode(result), StandardCharsets.UTF_8);
    } catch (Exception e) {
      throw new RuntimeException("AES加密失败", e);
    }
  }

  /**
   * AES 解密操作
   *
   * @param content 待解密密文内容
   * @param key 秘钥
   * @return 返回解密后的明文数据
   */
  public static String decrypt(String content, String key) {
    try {
      Cipher cipher = Cipher.getInstance(TRANSFORMATION);
      // 通过随机串生成一个AES对称秘钥，然后使用该秘钥对content进行AES对称解密
      cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
      byte[] result = cipher.doFinal(Base64.getDecoder().decode(content));
      return new String(result, StandardCharsets.UTF_8);
    } catch (Exception e) {
      throw new RuntimeException("AES解密失败", e);
    }
  }

  /**
   * 通过一个随机字符串：生成AES加密秘钥(用于内容加密)
   *
   * @param key 随机字符串
   * @return AES秘钥
   * @throws Exception 抛出异常
   */
  private static SecretKeySpec getSecretKey(final String key) throws Exception {
    // 返回生成指定算法密钥生成器的 KeyGenerator对象
    KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
    SecureRandom secureRandom = SecureRandom.getInstance(SHA_ALGORITHM);
    secureRandom.setSeed(key.getBytes());
    // 密钥长度为 128
    kg.init(128, secureRandom);
    // 生成一个密钥
    SecretKey secretKey = kg.generateKey();
    return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
  }
}
